package com.ict.ms.controller;

//import DistractHistoryStatistics.StatisticsInterface;

import DistractHistoryStatistics.StatisticsInterface;
import com.ict.ms.common.ProperGet;
import com.ict.ms.common.StateEnum;
import com.ict.ms.common.StateMsg;
import com.ict.ms.trackPlayBack.facade.dto.*;
import com.ict.ms.trackPlayBack.facade.api.IHistoryAnalysisService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ict.ms.common.ProperGet;
import com.ict.ms.common.StateEnum;
import com.ict.ms.common.StateMsg;
import com.ict.ms.trackPlayBack.facade.api.IHistoryAnalysisService;
import com.ict.ms.trackPlayBack.facade.dto.AreaParams;
import com.ict.ms.trackPlayBack.facade.dto.Circular;
import com.ict.ms.trackPlayBack.facade.dto.CircularSector;
import com.ict.ms.trackPlayBack.facade.dto.ResultObjWithCount;
import com.ict.ms.area.facade.api.IAreaOpeService;
import DistractHistoryStatistics.StatisticsInterface;
import com.ict.ms.area.facade.model.Area;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;

/**
 * Created by chenlong on 2016/11/17.
 */

/**
 * 态势回放
 */

@Controller
@RequestMapping({"/track"})
public class TrackAnalysisController {
    @Resource
    IHistoryAnalysisService historyAnalysisService;
    @Resource
    IAreaOpeService areaOpeService;
    /**
     * 矩形区域流量分析——mysql版本
     * @param map
     * @param ldlon
     * @param ldlat
     * @param rulon
     * @param rulat
     * @param startTime
     * @param endTime
     * @param mode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "analysis.do",method = RequestMethod.POST)
    public String analysis(ModelMap map,
                           @RequestParam(value="ldlon", required = false) double ldlon,
                           @RequestParam(value="ldlat", required = false) double ldlat,
                           @RequestParam(value="rulon", required = false) double rulon,
                           @RequestParam(value="rulat", required = false) double rulat,
                           @RequestParam(value="startTime", required = false) int startTime,
                           @RequestParam(value="endTime", required = false) int endTime,
                           @RequestParam(value="mode", required = false) int mode) {

        String jsonStr="";

        int intX60W_ldlon=(int) (ldlon * 600000);
        int intX60W_ldlat=(int) (ldlat * 600000);
        int intX60W_rulon=(int) (rulon * 600000);
        int intX60W_rulat=(int) (rulat * 600000);

        AreaParams areaParams = new AreaParams(intX60W_ldlon, intX60W_ldlat, intX60W_rulon,
                intX60W_rulat, startTime, endTime);

//        ResultObjWithCount resultObj=historyService.getAnalysis(areaParams,mode);
        ResultObjWithCount resultObj=historyAnalysisService.getAnalysis(areaParams,mode);

        if(resultObj.getState()==-1){
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
        }else if (resultObj.getState()==1){
            map.addAttribute("analysisList",resultObj.getObj());
            jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
        }else{
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
        }
        return jsonStr;
    }

    /**
     * 扇（环）形区域流量分析
     * @param map
     * @param cirlon
     * @param cirlat
     * @param ridius
     * @param radsmal
     * @param startDeg
     * @param endDeg
     * @param startTime
     * @param endTime
     * @param mode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "analysisSector.do",method = RequestMethod.POST)
    public String analysisSector(ModelMap map,
                                    @RequestParam(value="lon", required = false) double cirlon,
                                    @RequestParam(value="lat", required = false) double cirlat,
                                    @RequestParam(value="radius", required = false) double ridius,
                                    @RequestParam(value="radsmal", required = false) double radsmal,
                                    @RequestParam(value="startDeg", required = false) double startDeg,
                                    @RequestParam(value="endDeg", required = false) double endDeg,
                                    @RequestParam(value="startTime", required = false) int startTime,
                                    @RequestParam(value="endTime", required = false) int endTime,
                                    @RequestParam(value="mode", required = false) int mode) {
        String jsonStr = "";
        //通过圆形计算出外切矩形
        //半径（米）转成最大经度和最大纬度
        double lonRidius = ridius / 110000;//此处取赤道最大值
        double latRidius = ridius / 110000;

        int intX60W_ldlon = (int) ((cirlon - lonRidius) * 600000);
        int intX60W_ldlat = (int) ((cirlat - latRidius) * 600000);
        int intX60W_rulon = (int) ((cirlon + lonRidius) * 600000);
        int intX60W_rulat = (int) ((cirlat + latRidius) * 600000);

        AreaParams areaParams = new AreaParams(intX60W_ldlon, intX60W_ldlat, intX60W_rulon,
                intX60W_rulat, startTime, endTime);

        CircularSector circularSector = new CircularSector(cirlon, cirlat, ridius, radsmal, startDeg, endDeg);

        ResultObjWithCount resultObj=historyAnalysisService.analysisSector(mode,areaParams,circularSector);

        if(resultObj.getState()==-1){
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
        }else if (resultObj.getState()==1){
            map.addAttribute("analysisList",resultObj.getObj());
            jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
        }else {
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
        }
        return jsonStr;
    }

        /**
         * 圆形区域流量分析——mysql版本
         * @param map
         * @param cirlon
         * @param cirlat
         * @param ridius
         * @param startTime
         * @param endTime
         * @param mode
         * @return
         */

    @ResponseBody
    @RequestMapping(value = "analysisCircular.do",method = RequestMethod.POST)
    public String analysisCircular(ModelMap map,
                                      @RequestParam(value="cirlon", required = false) double cirlon,
                                      @RequestParam(value="cirlat", required = false) double cirlat,
                                      @RequestParam(value="radius", required = false) double ridius,
                                      @RequestParam(value="startTime", required = false) int startTime,
                                      @RequestParam(value="endTime", required = false) int endTime,
                                      @RequestParam(value="mode", required = false) int mode) {
        String jsonStr="";

        //通过圆形计算出外切矩形
        //半径（米）转成最大经度和最大纬度
        double lonRidius=ridius/110000;//此处取赤道最大值
        double latRidius=ridius/110000;

        int intX60W_ldlon=(int) ((cirlon-lonRidius) * 600000);
        int intX60W_ldlat=(int) ((cirlat-latRidius) * 600000);
        int intX60W_rulon=(int) ((cirlon+lonRidius) * 600000);
        int intX60W_rulat=(int) ((cirlat+latRidius) * 600000);

        AreaParams areaParams = new AreaParams(intX60W_ldlon, intX60W_ldlat, intX60W_rulon,
                intX60W_rulat, startTime, endTime);

        Circular circular=new Circular(cirlon,cirlat,ridius);

        ResultObjWithCount resultObj=historyAnalysisService.getAnalysisCirCular(mode,areaParams,circular);

        if(resultObj.getState()==-1){
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
        }else if (resultObj.getState()==1){
            map.addAttribute("analysisList",resultObj.getObj());
            jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
        }else {
            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
        }
        return jsonStr;
    }

    /**
     * 多边形区域流量分析
     * @param map
     * @param lonStrArr
     * @param latStrArr
     * @param startTime
     * @param endTime
     * @param mode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "analysisPolygons.do",method = RequestMethod.POST)
    public String analysisPolygons(ModelMap map, @RequestParam(value = "lonStrArr",required = false) String lonStrArr,
                                     @RequestParam(value = "latStrArr",required = false) String latStrArr,
                                     @RequestParam(value="startTime", required = false) int startTime,
                                     @RequestParam(value="endTime", required = false) int endTime,
                                     @RequestParam(value="mode", required = false) int mode) {

        String msg;
        String jsonStr="";
        try {
            String[] lonArr = com.ict.ms.realTime.facade.common.SplitUtils.MDVNumSplit_StrArray(lonStrArr);
            String[] latArr = com.ict.ms.realTime.facade.common.SplitUtils.MDVNumSplit_StrArray(latStrArr);
            if(lonArr.length!=latArr.length){
                msg="参数错误";
                map.addAttribute("result",msg);
                jsonStr=StateMsg.toJson(-2,map);
                return jsonStr;
            }else {

                Double[] point_x=new Double[lonArr.length];
                Double[] point_y=new Double[latArr.length];

                for (int i=0;i<lonArr.length;i++){
                    point_x[i]=Double.parseDouble(lonArr[i]);
                    point_y[i]=Double.parseDouble(latArr[i]);
                }

                ArrayList<Double> point_x_list = new ArrayList<Double>(Arrays.asList(point_x));
                ArrayList<Double> point_y_list = new ArrayList<Double>(Arrays.asList(point_y));

                //得到多边形外切矩形用于sql语句筛选目标
                double minLon=point_x[0];
                double minLat=point_y[0];
                double maxLon=point_x[0];
                double maxLat=point_y[0];

                for (int j=0;j<point_x.length;j++){
                    if(point_x[j]<minLon){
                        minLon=point_x[j];
                    }
                    if(point_x[j]>maxLon){
                        maxLon=point_x[j];
                    }

                    if(point_y[j]<minLat){
                        minLat=point_y[j];
                    }
                    if(point_y[j]>maxLat){
                        maxLat=point_y[j];
                    }
                }

                int intX60W_ldlon=(int) (minLon * 600000);
                int intX60W_ldlat=(int) (minLat * 600000);
                int intX60W_rulon=(int) (maxLon * 600000);
                int intX60W_rulat=(int) (maxLat * 600000);

//                System.out.println("X60W以后的外切矩形的经纬度："+minLon+","+minLat+","+maxLon+","+maxLat);

                AreaParams areaParams = new AreaParams(intX60W_ldlon, intX60W_ldlat, intX60W_rulon,
                        intX60W_rulat, startTime, endTime);

                ResultObjWithCount resultObj=historyAnalysisService.getAnalysisPolygons(mode,areaParams,point_x_list,point_y_list);

                if(resultObj.getState()==-1){
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
                }else if(resultObj.getState()==0){
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
                }else{
                    map.addAttribute("analysisList",resultObj.getObj());
                    jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
                }
                return jsonStr;
            }
        }catch (Exception e){
            msg="参数错误";
            map.addAttribute("result",msg);
            jsonStr=StateMsg.toJson(-2,map);
            return jsonStr;
        }
    }

        /**
     * 区域流量分析——调用孙涛版本
     * @param map
     * @param ldlon
     * @param ldlat
     * @param rulon
     * @param rulat
     * @param startTime
     * @param endTime
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "analysisHive.do",method = RequestMethod.POST)
    public String areaDistract(ModelMap map,
                               @RequestParam(value="ldlon", required = false) double ldlon,
                               @RequestParam(value="ldlat", required = false) double ldlat,
                               @RequestParam(value="rulon", required = false) double rulon,
                               @RequestParam(value="rulat", required = false) double rulat,
                               @RequestParam(value="startTime", required = false) int startTime,
                               @RequestParam(value="endTime", required = false) int endTime,
                               @RequestParam(value="mode", required = false) int mode) {

        String msg;
        String jsonStr = "";

        //数据库配置参数Hive
        String dbType = "Hive"; //目前可以支持的为Hive以及MySQL，严格区分大小写。

        //查询表名和查询列，这里可以区分融合模式和原始模式

        String tableName="";
        String columName="";

        if(mode==0){
            //融合模式
            tableName = "l1_target_history_positions_hive";
            columName = "Target_ID, Record_UTC_Time, Longitude, Latitude, MMSI, Country_Name, Aggregated_AIS_Ship_Type_ID";
        }else if (mode==1){
            //原始模式
            tableName = "l1_target_history_positions_hive";
            columName = "Target_ID_Orig, Record_UTC_Time, Longitude, Latitude, MMSI, Country_Name, AIS_Ship_Type";
        }

        /*
        提供1，2两种查询语句
        1的时间长，返回结果无纰漏
        2的时间短，但当数据点有异常值时会少数据，这里异常指相邻两点间距离过大
         */
//        String accuracy = "1";
        String accuracy = "2";

        //设置统计船舶的类型，此处统计1-7类型，剩余类型全部归为其他
        ArrayList<Integer> shipTypeList = new ArrayList<Integer>();
        for (int i = 1; i < 9; i++) {
            shipTypeList.add(i);
        }

//        //如果需要按照指定国家统计则传入该List
//        //设置统计国家，此处添加中国，美国，剩余国家归为其他。
//        ArrayList<String> countryList = new ArrayList<String>();
//        countryList.add("中国");
//        countryList.add("美国");

        try{
            ProperGet properGet=new ProperGet("/DistractHistoryAnalyInterface.properties");
            properGet.toString();

            int intX60W_ldlon=(int) (ldlon * 600000);
            int intX60W_ldlat=(int) (ldlat * 600000);
            int intX60W_rulon=(int) (rulon * 600000);
            int intX60W_rulat=(int) (rulat * 600000);
            //按参数初始化
            StatisticsInterface statisticsInterface = new StatisticsInterface(properGet.getHive_ip(), Integer.parseInt(properGet.getHive_port()),
                    properGet.getHive_user(), properGet.getHive_psword(), dbType, tableName, columName, accuracy);

            net.sf.json.JSONArray jsonArray=statisticsInterface.resultShipTypeListCountryList(intX60W_ldlon, intX60W_ldlat,
                    intX60W_rulon,intX60W_rulat,startTime,endTime,shipTypeList);

            System.out.println(jsonArray);
            map.addAttribute("shipList",jsonArray);
            jsonStr = StateMsg.toJson(1, map);
            return jsonStr;
        }catch (Exception e){
            System.out.println("出现异常"+e);
            msg="获取指定区域船舶信息失败";
            map.addAttribute("error",msg);
            jsonStr = StateMsg.toJson(-1, map);
            return jsonStr;
        }
    }

    /*
    * 列表选择历史区域统计 */
    @ResponseBody
    @RequestMapping(value ="histSelectAreaCount.do",method = RequestMethod.POST)
    public String SelectAarea(ModelMap map,
                              @RequestParam(value="id", required = false) int id,
                              @RequestParam(value = "startTime",required = false) int startTime,
                              @RequestParam(value = "endTime",required = false)int endTime,
                              @RequestParam(value = "limit",required = false)int limit,
                              @RequestParam(value = "mode",required = false)int mode){

        String msg = "";
        String jsonStr = "";
        Area area = areaOpeService.getArea(id,255);
        int shap = area.getShape();
        switch (shap){
            case 1:
                int ridius = area.getRadius();
                int cirlon = area.getCentreLon();
                int cirlat = area.getCentreLat();

                double lonRidius=ridius;//此处取赤道最大值
                double latRidius=ridius;

                int intX60W_ldlon_1=(int) ((cirlon-lonRidius) );
                int intX60W_ldlat_1=(int) ((cirlat-latRidius) );
                int intX60W_rulon_1=(int) ((cirlon+lonRidius) );
                int intX60W_rulat_1=(int) ((cirlat+latRidius) );

                AreaParams areaParams_1 = new AreaParams(intX60W_ldlon_1, intX60W_ldlat_1, intX60W_rulon_1,
                        intX60W_rulat_1, startTime, endTime);

                Circular circular=new Circular(cirlon,cirlat,ridius);

                ResultObjWithCount resultObj_1=historyAnalysisService.getAnalysisCirCular(mode,areaParams_1,circular);

                if(resultObj_1.getState()==-1){
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
                }else if (resultObj_1.getState()==1){
                    map.addAttribute("analysisList",resultObj_1.getObj());
                    jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
                }else {
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
                }
            case 2:
                int ldlat = area.getLdlat();
                int ldlon = area.getLdlon();
                int rulat = area.getRulat();
                int rulon = area.getRulon();

                int intX60W_ldlon_2=(int) (ldlon );
                int intX60W_ldlat_2=(int) (ldlat );
                int intX60W_rulon_2=(int) (rulon );
                int intX60W_rulat_2=(int) (rulat );

                AreaParams areaParams_2 = new AreaParams(intX60W_ldlon_2, intX60W_ldlat_2, intX60W_rulon_2,
                        intX60W_rulat_2, startTime, endTime);

                ResultObjWithCount resultObj_2=historyAnalysisService.getAnalysis(areaParams_2,mode);

                if(resultObj_2.getState()==-1){
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
                }else if (resultObj_2.getState()==1){
                    map.addAttribute("analysisList",resultObj_2.getObj());
                    jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
                }else{
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
                }
            case 3:
                Integer lonStrArr = area.getLdlon();
                Integer latStrArr = area.getLdlat();
                try {

                    String[] lonArr = com.ict.ms.realTime.facade.common.SplitUtils.MDVNumSplit_StrArray(lonStrArr.toString());
                    String[] latArr = com.ict.ms.realTime.facade.common.SplitUtils.MDVNumSplit_StrArray(latStrArr.toString());
                    if(lonArr.length!=latArr.length){
                        msg="参数错误";
                        map.addAttribute("result",msg);
                        jsonStr=StateMsg.toJson(-2,map);
                        return jsonStr;
                    }else {

                        Double[] point_x=new Double[lonArr.length];
                        Double[] point_y=new Double[latArr.length];

                        for (int i=0;i<lonArr.length;i++){
                            point_x[i]=Double.parseDouble(lonArr[i]);
                            point_y[i]=Double.parseDouble(latArr[i]);
                        }

                        ArrayList<Double> point_x_list = new ArrayList<Double>(Arrays.asList(point_x));
                        ArrayList<Double> point_y_list = new ArrayList<Double>(Arrays.asList(point_y));

                        //得到多边形外切矩形用于sql语句筛选目标
                        double minLon=point_x[0];
                        double minLat=point_y[0];
                        double maxLon=point_x[0];
                        double maxLat=point_y[0];

                        for (int j=0;j<point_x.length;j++){
                            if(point_x[j]<minLon){
                                minLon=point_x[j];
                            }
                            if(point_x[j]>maxLon){
                                maxLon=point_x[j];
                            }

                            if(point_y[j]<minLat){
                                minLat=point_y[j];
                            }
                            if(point_y[j]>maxLat){
                                maxLat=point_y[j];
                            }
                        }

                        int intX60W_ldlon_3=(int) (minLon);
                        int intX60W_ldlat_3=(int) (minLat);
                        int intX60W_rulon_3=(int) (maxLon);
                        int intX60W_rulat_3=(int) (maxLat);

                        AreaParams areaParams = new AreaParams(intX60W_ldlon_3, intX60W_ldlat_3, intX60W_rulon_3,
                                intX60W_rulat_3, startTime, endTime);

                        ResultObjWithCount resultObj_3=historyAnalysisService.getAnalysisPolygons(mode,areaParams,point_x_list,point_y_list);

                        if(resultObj_3.getState()==-1){
                            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
                        }else if(resultObj_3.getState()==0){
                            jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
                        }else{
                            map.addAttribute("analysisList",resultObj_3.getObj());
                            jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
                        }

                    }
                }catch (Exception e){
                    msg="参数错误";
                    map.addAttribute("result",msg);
                    jsonStr=StateMsg.toJson(-2,map);
                    return jsonStr;
                }
            case 4:
                int ridius_4 = area.getRadius();
                double lonRidius_4 = ridius_4 ;//此处取赤道最大值
                double latRidius_4 = ridius_4 ;
                int radsmal = area.getRadsmal();
                int cirlon_4 = area.getCentreLon();
                int cirlat_4= area.getCentreLat();
                double startDeg = area.getStart_deg();
                double endDeg = area.getEnd_deg();
                int intX60W_ldlon = (int) ((cirlon_4 - lonRidius_4));
                int intX60W_ldlat = (int) ((cirlat_4 - latRidius_4));
                int intX60W_rulon = (int) ((cirlon_4 + lonRidius_4));
                int intX60W_rulat = (int) ((cirlat_4 + latRidius_4) );

                AreaParams areaParams = new AreaParams(intX60W_ldlon, intX60W_ldlat, intX60W_rulon,
                        intX60W_rulat, startTime, endTime);

                CircularSector circularSector = new CircularSector(cirlon_4, cirlat_4, ridius_4, radsmal, startDeg, endDeg);

                ResultObjWithCount resultObj_4=historyAnalysisService.analysisSector(mode,areaParams,circularSector);

                if(resultObj_4.getState()==-1){
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SQLExcuteError,map);
                }else if (resultObj_4.getState()==1){
                    map.addAttribute("analysisList",resultObj_4.getObj());
                    jsonStr=StateMsg.toJsonOSE(StateEnum.StateCode.Success_All,map);
                }else {
                    jsonStr= StateMsg.toJsonOSE(StateEnum.StateCode.SelectNull,map);
                }
        }
    return jsonStr;
    }

}